package com.hb.config;

import org.neo4j.graphdb.GraphDatabaseService;
import org.neo4j.graphdb.factory.GraphDatabaseFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.data.neo4j.config.EnableNeo4jRepositories;
import org.springframework.data.neo4j.config.Neo4jConfiguration;
import org.springframework.data.neo4j.rest.SpringRestGraphDatabase;

@Configuration
// 启用 Repository 自动生成功能
// @EnableNeo4jRepositories 注解能够让 Spring Data Neo4j 自动生成 Neo4j Repository 实现。它的 basePackages 属性设置为 com.hb.repository 包，
// 这样它就会扫描这个包来查找（直接或间接）扩展 Repository 标记接口的其他接口。
@EnableNeo4jRepositories(basePackages = "com.hb.repository")
/**
 * Neo4jConfig 扩展自 Neo4jConfiguration，后者提供了多个便利的方法来配置 Spring Data Neo4j。在这些方法中，就包括 setBasePackage()，它会在 Neo4jConfig 的构造器中调用，
 * 用来告诉 Spring Data Neo4j 要在 com.hb.model 包中查找模型类。
 */
public class Neo4jConfig extends Neo4jConfiguration {
    public Neo4jConfig() {
        // 设置模型的基础包
        setBasePackage("com.hb.model");
    }

    /**
     * graphDatabaseService() 方法使用 GraphDatabaseFactory 来创建嵌入式的 Neo4j 数据库。在 Neo4j 中，嵌入式数据库不要与内存数据库相混淆。在这里，“嵌入式”指的
     * 是数据库引擎与应用运行在同一个 JVM 中，作为应用的一部分，而不是独立的服务器。数据依然会持久化到文件系统中（在本例中，也就是 “/tmp/graphdb” 中）。
     *
     * @return
     */
    @Bean(destroyMethod = "shutdown")
    public GraphDatabaseService graphDatabaseService() {
        // 配置嵌入式数据库
        return new GraphDatabaseFactory().newEmbeddedDatabase("/tmp/graphdb");
    }

    /**
     * 作为另外的一种方式，你可能会希望配置 GraphDatabaseService 连接远程的 Neo4j 服务器。如果 spring-data-neo4j-rest 库在应用的类路径下，那么我们就可以配
     * 置 SpringRestGraphDatabase，它会通过 RESTful API 来访问远程的 Neo4j 数据库。
     *
     * @return
     */
    @Bean
    public SpringRestGraphDatabase graphRemoteDatabaseService(Environment env) {
        // 在生产环境的配置中，当创建 SpringRestGraphDatabase 的时候，我们可能希望提供应用的凭证。
        // 在这里，凭证是通过注入的 Environment 获取到的，避免了在配置类中的硬编码。
        return new SpringRestGraphDatabase("http://graphdbserver:7474/db/data/", env.getProperty("db.username"), env.getProperty("db.password"));
    }
}
